package org.aplikator.client.shared.descriptor;

import org.aplikator.client.shared.data.ListItem;
import org.aplikator.client.shared.data.Record;
import org.jboss.errai.common.client.api.annotations.Portable;

import java.io.Serializable;
import java.util.List;

@SuppressWarnings("serial")
@Portable
public class PropertyDTO extends ClientDescriptorBase implements Serializable {

    private String type;
    private double size;
    private PropertyDTO refferedThrough;
    private List<ListItem> listValues;
    private boolean editable;

    private boolean noChange = false;

    @SuppressWarnings("unused")
    public PropertyDTO() { //TODO custom marshaller
    }

    public PropertyDTO(String id, String localizedName, String type, double size, PropertyDTO refferedThrough, boolean editable) {
        super(id, localizedName);
        this.type = type;
        this.size = size;
        this.refferedThrough = refferedThrough;
        this.editable = editable;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
		this.type = type;
	}
    
    public double getSize() {
        return size;
    }
    
    public void setSize(double size) {
		this.size = size;
	}

    public PropertyDTO getRefferedThrough() {
        return refferedThrough;
    }

    public void setRefferedThrough(PropertyDTO refferedThrough) {
		this.refferedThrough = refferedThrough;
	}
    
    String getRecordId(){
        if (getRefferedThrough()!= null){
            return getRefferedThrough().getRecordId()+PATH_DELIMITER+getId();
        } else {
            return getId();
        }
    }

    @SuppressWarnings("unchecked")
    public Serializable getValue(Record record){
        return  (Serializable)record.getValue(getRecordId());
    }

    public void setValue(Record record, Serializable value){
        record.setValue(getRecordId(),value);
    }

    @Override
    public String toString() {
        return getId();
    }

    public void setListValues(List<ListItem> listValues) {
        this.listValues = listValues;
    }

    public List<ListItem> getListValues() {
        return listValues;
    }

    /*
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if ((this.refferedThrough != null) && (((PropertyDTO<?>) obj).getRefferedThrough() != null)) {
            return this.refferedThrough.equals(((PropertyDTO<?>) obj).getRefferedThrough());
        } else if ((this.refferedThrough == null) && ((PropertyDTO<?>) obj).getRefferedThrough() == null) {
            return true;
        } else
            return false;
    }*/


    public PropertyDTO cloneUnreferenced() {
        PropertyDTO retval = new PropertyDTO(getId(), getLocalizedName(), getType(), getSize(), null, isEditable());
        retval.setListValues(getListValues());
        return retval;
    }

    public boolean isNoChange() {
        return noChange;
    }

    public void setNoChange(boolean noChange) {
        this.noChange = noChange;
    }

    public boolean isEditable() {
        return editable;
    }

    public void setEditable(boolean editable) {
        this.editable = editable;
    }


    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((refferedThrough == null) ? 0 : refferedThrough.hashCode());
        return result;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (!(obj instanceof PropertyDTO))
            return false;
        PropertyDTO other = (PropertyDTO) obj;
        if (refferedThrough == null) {
            if (other.refferedThrough != null)
                return false;
        } else if (!refferedThrough.equals(other.refferedThrough))
            return false;
        return true;
    }

}
